package com.dcjt.firehotcarpad.fragment

import LocationPool
import MapOperationEventPool
import android.annotation.SuppressLint
import android.location.Location
import android.os.Bundle
import android.util.SparseArray
import android.view.View
import android.widget.CheckBox
import android.widget.RelativeLayout
import androidx.core.util.forEach
import androidx.lifecycle.ViewModelProviders
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMap
import com.amap.api.maps.AMapUtils
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.maps.model.animation.Animation
import com.amap.api.maps.model.animation.ScaleAnimation
import com.amap.api.navi.AMapNaviIndependentRouteListener
import com.amap.api.navi.model.AMapCalcRouteResult
import com.amap.api.navi.model.AMapNaviPathGroup
import com.amap.api.navi.model.NaviLatLng
import com.amap.api.navi.model.NaviPoi
import com.amap.api.navi.view.RouteOverLay
import com.aries.library.fast.manager.LoggerManager
import com.aries.library.fast.util.FastStackUtil
import com.aries.library.fast.util.SPUtil
import com.aries.library.fast.util.ToastUtil
import com.aries.ui.view.radius.RadiusTextView
import com.dcjt.firehotcarpad.R
import com.dcjt.firehotcarpad.adapter.MapWindowInfoAdapter
import com.dcjt.firehotcarpad.base.ApiPath
import com.dcjt.firehotcarpad.base.App
import com.dcjt.firehotcarpad.base.SPConstant
import com.dcjt.firehotcarpad.entity.MapEvent
import com.dcjt.firehotcarpad.helper.NavTypeSelectHelper
import com.dcjt.firehotcarpad.model.HandleDisasterViewModel
import com.dcjt.firehotcarpad.model.SendMessageUtils
import com.dcjt.firehotcarpad.moudle.HandleDisasterActivity
import com.dcjt.firehotcarpad.moudle.NavActivity
import com.dcjt.firehotcarpad.utils.AlertDialogUtil
import com.dcjt.firehotcarpad.utils.Converter
import com.dcjt.firehotcarpad.utils.LocationType
import com.dcjt.firehotcarpad.utils.MapUtils
import kotlinx.android.synthetic.main.layout_car_status.*
import org.simple.eventbus.Subscriber
import org.simple.eventbus.ThreadMode
import java.text.DecimalFormat


/**
 * Created by cj on 9:22.
 * Email:codesexy@163.com
 * Function:
 * desc:
 */

class MapFragment1 : BaseMapFragment(), LocationPool.LocationChangeObserver,
    AMap.OnMarkerClickListener, AMapNaviIndependentRouteListener,
    MapOperationEventPool.MapOperationEventObserver , NewMessagePool.NewMessageObserverObserver {

    //标绘上图的marker
    private var biaohuiMarkers = mutableListOf<Marker>()
    //标绘上图的Polygon
    private var biaohuiPolygon = mutableListOf<Polygon>()
    //标绘上图的Circle
    private var biaohuiCircle = mutableListOf<Circle>()
    //标绘上图的Polyline
    private var biaohuiPolyline = mutableListOf<Polyline>()
    //保存水源上图的marker
    private var waterSourceMarkers = mutableListOf<Marker>()

    //保存灾情上图的marker
    private var disasterMarkers = mutableListOf<Marker>()
    lateinit var handleViewModel: HandleDisasterViewModel

    //当前正在显示infoWindow的Marker
    private var showInfoMarker: Marker? = null
    private var zqid: String = ""
    private var zqxxMarkerMap: HashMap<LocationType,Marker> = HashMap<LocationType,Marker>()

    /**
     * 保存当前算好的路线
     */
    private val routeOverlays = SparseArray<RouteOverLay>()

    private var routeIndex = 0

    //算出来的路径
    private var naviPathGroup: AMapNaviPathGroup? = null

    //当前路径规划的终点
    private var currentNavPoint: LatLng? = null
    private var  cbBiaohui: CheckBox? = null

    companion object {
        fun newInstance(): MapFragment1 {
            val fragment = MapFragment1()
            return fragment
        }
    }

    override fun getContentLayout(): Int = R.layout.fragment_map

    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)
        findViewById<RelativeLayout>(R.id.myLocation)?.setOnClickListener { toMyLocation() }
        findViewById<RelativeLayout>(R.id.zoomOut)?.setOnClickListener { zoomOut() }
        findViewById<RelativeLayout>(R.id.zoomIn)?.setOnClickListener { zoomIn() }

        val planType = findViewById<RadiusTextView>(R.id.rtv_plan_type)
        cbBiaohui = findViewById<CheckBox>(R.id.cb_biaohui)
        if (requireActivity() is HandleDisasterActivity) {
            handleViewModel =
                ViewModelProviders.of(requireActivity()).get(HandleDisasterViewModel::class.java)
            handleViewModel.getDisasterInfo().observe(this, androidx.lifecycle.Observer { entity ->
                if (entity != null) {
                    zqid = entity.zqxx!!.id!!
                }
            })
            handleViewModel.biaohuiLivaData.observe(this, androidx.lifecycle.Observer { entity ->
                    //上图
                    if (entity != null && entity.isNotEmpty())
                        MapUtils.addBiaohuiOnMap(entity, aMap!!, biaohuiMarkers,biaohuiPolygon,biaohuiCircle,biaohuiPolyline)
            })
            planType?.visibility = View.VISIBLE
            planType?.setOnClickListener {
                NavTypeSelectHelper.showChoosePanel(this, planType) {
                    currentNavPoint?.let { calculatePath(it) }
                }
            }
            cbBiaohui?.visibility = View.VISIBLE
            cbBiaohui?.setOnCheckedChangeListener { _, isChecked ->
                if (isChecked){
                    //选中  网络请求标绘
                    if (zqid.isEmpty()){
                        ToastUtil.show("警情id为空，不可查询")
                        return@setOnCheckedChangeListener
                    }
                    handleViewModel.loadBiaohuiList(zqid,"")
                } else{
                    //通知map 取消标绘
                    if (!biaohuiMarkers.isNullOrEmpty()){
                        biaohuiMarkers.forEach { it.remove() }
                    }
                    if (!biaohuiCircle.isNullOrEmpty()){
                        biaohuiCircle.forEach { it.remove() }
                    }
                    if (!biaohuiPolygon.isNullOrEmpty()){
                        biaohuiPolygon.forEach { it.remove() }
                    }
                    if (!biaohuiPolyline.isNullOrEmpty()){
                        biaohuiPolyline.forEach { it.remove() }
                    }

                }
            }

        }


        NewMessagePool.get().registerNewMessageObserver(this)
        MapOperationEventPool.get().registerMapOperationEventObserver(this)
        //位置变化
        LocationPool.get().registerLocationObserver(this)
        aMap!!.setOnMarkerClickListener(this)
        //处理弹框
        aMap!!.setInfoWindowAdapter(MapWindowInfoAdapter())

    }

    override fun onMyLocationChange(location: Location?) {
        super.onMyLocationChange(location)
    }

    /**
     * c处理发送来的消息
     */
    private fun toDealWithLatlon(t: MapEvent) {
        //经纬度转换
        var latlon = Converter.toGCJ02Point_latlon(
            t.latLng.latitude,
            t.latLng.longitude
        )
        if (t.isAddMarker) {
            if (zqxxMarkerMap[t.type] != null){
                zqxxMarkerMap[t.type]?.remove()
            }
            addMarkers(latlon, t.type)
        } else {
            startNav(latlon)
        }
    }

    override fun onMapOperationEvent(event: MapEvent) {
        if (requireActivity().javaClass == HandleDisasterActivity::class.java) {
            LoggerManager.e("LocationType_pool:" + event.type.desc + "---addMaker:" + event.isAddMarker)
            toDealWithLatlon(event)
        }

    }

    override fun onAddAroundWaterMakers(points: List<WaterSourceEntity>?,page: Int) {
        addAroundWaterMaker(points,page)
    }

    override fun onHintAroundWaterMakers() {
//        if (showInfoMarker != null && showInfoMarker!!.isInfoWindowShown) return
        if (waterSourceMarkers == null || waterSourceMarkers.size == 0) return
        waterSourceMarkers.forEach {
            it.isVisible = false
        }
    }

    override fun onShowAroundWaterMakers() {
        if (waterSourceMarkers == null || waterSourceMarkers.size == 0) return
        waterSourceMarkers.forEach {
            it.isVisible = true
        }
    }

    override fun onAddDisasterMakers(points: List<DisasterListInfoEntity>?,page:Int) {
        if (showInfoMarker != null && showInfoMarker!!.isInfoWindowShown) {
            showInfoMarker!!.hideInfoWindow()
        }
        if (disasterMarkers != null && disasterMarkers.size > 0 && page == 0) {
            disasterMarkers.forEach { it.remove() }
            disasterMarkers.clear()
        }
        if (points != null && points.isNotEmpty())
            MapUtils.addDisasterOnMap(points, aMap!!, disasterMarkers)
    }

    override fun onHintDisasterMakers() {
        if (disasterMarkers == null || disasterMarkers.size == 0) return
        disasterMarkers.forEach { it.isVisible = false }
    }

    override fun onShowDisasterMakers() {
        if (disasterMarkers == null || disasterMarkers.size == 0) return
        disasterMarkers.forEach { it.isVisible = true }
    }

    override fun onRemoveMakers() {
        if (showInfoMarker != null && showInfoMarker!!.isInfoWindowShown) {
            showInfoMarker!!.hideInfoWindow()
        }
        aMap!!.clear()
        biaohuiMarkers.clear()
        biaohuiPolygon.clear()
        biaohuiCircle.clear()
        biaohuiPolyline.clear()
        waterSourceMarkers.clear()
        disasterMarkers.clear()
    }

    override fun onImitateClickMarker(points: WaterSourceEntity) {
        if (waterSourceMarkers.size == 0) return
        for (marker in waterSourceMarkers) {
            if (marker.`object` == points) {
                onMarkerClick(marker)
                aMap!!.moveCamera(CameraUpdateFactory.changeLatLng(marker.position))
                return
            }
        }
    }

    override fun onUploadBiaoHuiMessage(zqId: String) {
        if (requireActivity().javaClass == HandleDisasterActivity::class.java) {
            if (zqid.isEmpty() ||zqId.isEmpty()){
                ToastUtil.show("警情id为空，不可查询")
                return
            }
            if (zqId == zqid){
                if (cbBiaohui?.isChecked!!){
                    handleViewModel.loadBiaohuiList(zqid,"")
                }
            }

        }
    }

    override fun onDestroy() {
        super.onDestroy()
        NewMessagePool.get().unRegisterNewMessageObserver(this)
        LocationPool.get().unRegisterLocationObserver(this)
        MapOperationEventPool.get().unRegisterMapOperationEventObserver(this)
        waterSourceMarkers.clear()
        disasterMarkers.clear()
        zqxxMarkerMap.clear()
        biaohuiMarkers.clear()
        biaohuiPolygon.clear()
        biaohuiCircle.clear()
        biaohuiPolyline.clear()
    }

    /**
     * 添加相应不同类型的marker
     * @param latLng
     * @param type
     */
    private fun addMarkers(latLng: LatLng, type: LocationType) {
        var marker = aMap!!.addMarker(MapUtils.createMapMarkerOption(latLng, type))
        var markerAnimation: Animation = ScaleAnimation(1.0f, 1.2f, 1.0f, 1.2f) // 缩放比例
        markerAnimation.setDuration(0) // 动画时间
        markerAnimation.fillMode = 1 // 动画之后保存的状态 1 动画之后的状态 0 动画之前的状态
        marker.setAnimation(markerAnimation) // 将动画赋值给当前的marker
        marker.setClickable(true) // marker设置为可点击状态
        zqxxMarkerMap[type] = marker
    }


    private fun startNav(endLatLng: LatLng) {
        if (App.navPathGroup == null) {
            alertChoicePathTips(endLatLng)
        } else {
            val endPoint = App.navPathGroup!!.mainPath.endPoint
            var distance = AMapUtils.calculateLineDistance(
                endLatLng,
                LatLng(endPoint.latitude, endPoint.longitude)
            )
            if (distance < 5) {
                //当终点和目前保存的路径重点一致的时候  就任务当前已经选择过了
                NavActivity.startNavActivity(
                    requireContext(),
                    endLatLng.latitude,
                    endLatLng.longitude, false
                )
            } else {
                alertChoicePathTips(endLatLng)
            }
        }
    }

    private fun alertChoicePathTips(endLatLng: LatLng) {
        calculatePath(endLatLng)
    }


    /**
     * 当前点到终点的路径规划
     * @param endLatLng 终点
     */
    private fun calculatePath(endLatLng: LatLng) {

        currentNavPoint = endLatLng;
        val endPoint = NaviPoi("终点", endLatLng, "")
//        val endPoint = NaviLatLng(endLatLng.latitude,endLatLng.longitude)
        val smart = SPUtil.get(context, SPConstant.TAG_SMART_RECOM, true) as Boolean
        val noHigh = SPUtil.get(context, SPConstant.TAG_NO_HIGH_SPEED, false) as Boolean
        val avoidCharge = SPUtil.get(context, SPConstant.TAG_AVOID_CHARGES, false) as Boolean
        val avoidCongest = SPUtil.get(context, SPConstant.TAG_AVOID_CONGESTION, false) as Boolean
        var strategy = if (smart) {
            mAMapNavi.strategyConvert(true, false, true, true, true)
        } else {
            mAMapNavi.strategyConvert(avoidCongest, noHigh, avoidCharge, false, false)
        }

        mAMapNavi.independentCalculateRoute(null, endPoint, null, strategy, 1, this)
//        mAMapNavi.calculateDriveRoute(arrayListOf(endPoint), null, strategy)
    }

    @SuppressLint("SetTextI18n")
    override fun onChange(location: AMapLocation) {
        gps.text = "GPS:${MapUtils.getGpsStatus(location)}"
        tvSpeed.text = "速度：${location.speed} m/s"
        tvDuration.text = "方向：${MapUtils.getGpsBearing(location)}"
        val format = DecimalFormat("0.###")
        tvLat.text = "纬度：${format.format(location.latitude)}"
        tvLon.text = "经度：${format.format(location.longitude)}"
    }


    @Subscriber(mode = ThreadMode.MAIN, tag = ApiPath.ADD_POINT_ON_MAP)
    fun addPointOnMap(points: List<WaterSourceEntity>) {
        // tips：infoWindow 正在显示的时候就不要再去清除地图上的marker了
        addAroundWaterMaker(points,0)
    }

    private fun addAroundWaterMaker(points: List<WaterSourceEntity>?,page: Int) {
        if (showInfoMarker != null && showInfoMarker!!.isInfoWindowShown) {
            showInfoMarker!!.hideInfoWindow()
        }

        if (waterSourceMarkers != null && waterSourceMarkers.size > 0 && page == 0) {
            waterSourceMarkers.forEach { it.remove() }
            waterSourceMarkers.clear()
        }
        if (points != null && points.isNotEmpty())
            MapUtils.addWaterSourceOnMap(points, aMap!!, waterSourceMarkers)
    }

    override fun onMarkerClick(marker: Marker?): Boolean {
        if (showInfoMarker != null) { // 判断之前放大的marker是否还在放大的状态
            showInfoMarker?.startAnimation(); // 将之前放大的marker实现还原的状态，启动动画
            setNotClickedMarkerAnim(); // 给之前的marker设置下一次点击需要放大的动画效果
        }
        showInfoMarker = marker; // 当前放大的marker赋值
        marker?.startAnimation(); // 放大marker的动画播放
        marker?.showInfoWindow(); // 显示当前marker的infowindow
        setClickedMarkerAnim(); // 设置放大marker的还原状态动画
        return false; // 返回:true 表示点击marker后marker不会移动到地图中心；返回false 表示点击marker后marker会自动移动到地图中心
    }

    /**
     * setting original animation
     */
    private fun setClickedMarkerAnim() {
        if (showInfoMarker != null) {
            val markerAnimation: Animation =
                ScaleAnimation(
                    1.2f,
                    1.0f,
                    1.2f,
                    1.0f
                ) // update original view
            markerAnimation.setDuration(0) //set anim time
            markerAnimation.fillMode = 1
            showInfoMarker?.setAnimation(markerAnimation)
        }
    }

    /**
     * click then big view marker
     */
    private fun setNotClickedMarkerAnim() {
        if (showInfoMarker != null) {
            val markerAnimation: Animation =
                ScaleAnimation(
                    1.0f,
                    1.2f,
                    1.0f,
                    1.2f
                ) //click then big view marker
            markerAnimation.setDuration(0)
            markerAnimation.fillMode = 1
            showInfoMarker?.setAnimation(markerAnimation)
        }
    }

    override fun onIndependentCalculateSuccess(naviPathGroup: AMapNaviPathGroup) {
        aMap!!.moveCamera(CameraUpdateFactory.changeTilt(0f))
        this.naviPathGroup = naviPathGroup
        routeIndex = 0
        addPathOnMap(naviPathGroup)
    }

    private fun addPathOnMap(naviPathGroup: AMapNaviPathGroup) {
        routeOverlays.forEach { _, overlay ->
            overlay.removeFromMap()
        }
        routeOverlays.clear()
        val pathCount = naviPathGroup.pathCount
        for (index in 0..pathCount) {
            if (index >= 1) return //大于一条路径就不添加了
            val path = naviPathGroup.getPath(index)
            val routeOverLay = RouteOverLay(aMap, path, requireContext())
            routeOverLay.isTrafficLine = false
            routeOverLay.addToMap()
            routeOverlays.put(index, routeOverLay)
        }
    }

    override fun onIndependentCalculateFail(calcRouteResult: AMapCalcRouteResult) {
        ToastUtil.show("获取路线出现错误")
    }

    override fun onPolylineClick(polyline: Polyline?) {
        super.onPolylineClick(polyline)
        if (polyline == null) return
        if (routeOverlays.size() > 1) {//多条路径
            var selectIndex = MapUtils.setClickPolyline(routeOverlays, routeIndex, polyline)
            if (selectIndex != -1) {
                routeIndex = selectIndex
                this.naviPathGroup?.let {
                    it.selectRouteWithIndex(selectIndex)
                    App.navPathGroup = it
                }
                val endPoint = this.naviPathGroup?.getPath(routeIndex)?.endPoint
                alertChoiceEnsureDialog(endPoint)
            }
        } else {
            this.naviPathGroup?.selectRouteWithIndex(routeIndex)
            val endPoint = this.naviPathGroup?.getPath(routeIndex)?.endPoint
            //直接开始导航
            endPoint?.let {
                NavActivity.startNavActivity(
                    requireContext(),
                    it.latitude,
                    it.longitude
                )
            }
        }
    }

    private fun alertChoiceEnsureDialog(endPoint: NaviLatLng?) {
        if (endPoint == null) {
            ToastUtil.show("定位信息有误")
            return
        }

        AlertDialogUtil.alertTips(requireContext(),
            resources.getString(R.string.tips),
            resources.getString(R.string.ensureChoicePath),
            {},
            {
                NavActivity.startNavActivity(
                    requireContext(),
                    endPoint.latitude,
                    endPoint.longitude,
                    false
                )
            }
        )

    }


}
